﻿using Report_Dal.Web;
using Report_IDal.Web;
using Report_IService.Web;
using Report_Model.Basic;
using Report_Model.Db;
using Report_Model.Web;
using Report_Service.Basic;
using Report_Unity.Basic;
using Report_Unity.Unitys;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Report_Service.Web
{
    public class T_UserService : BaseService<T_User>, IT_UserService
    {
        private IT_UserDal T_UserDal = new T_UserDal(ConfigSource.tab_web);
        private IT_Login_RecordDal T_Login_RecordDal = new T_Login_RecordDal(ConfigSource.tab_web);
        private IT_Ticket_RecordDal T_Ticket_RecordDal = new T_Ticket_RecordDal(ConfigSource.tab_web);
        private IT_EmployeeDal T_EmployeeDal = new T_EmployeeDal(ConfigSource.tab_web);


        private IMsgService MsgService = new KAJRMsgService();

        public override void SetCurrentDal()
        {
            base.BaseDal = T_UserDal;
        }

        public ResultInfo RegOrLoginWithCode(string hid, string phone, string code, string ipaddr)
        {
            if (string.IsNullOrEmpty(hid))
                return CodeStatus.error_201.GetStatus($"{nameof(hid)}必传");
            if (string.IsNullOrEmpty(phone))
                return CodeStatus.error_201.GetStatus($"{nameof(phone)}必传");
            if (string.IsNullOrEmpty(code))
                return CodeStatus.error_201.GetStatus($"{nameof(code)}必传");
            if (string.IsNullOrEmpty(ipaddr))
                return CodeStatus.error_201.GetStatus($"{nameof(ipaddr)}必传");

            ResultInfo res = VerifyHelper.VeifyCode(phone, code);
            if (res.code != CodeStatus.success.GetHashCode())
                return res;

            T_User user = GetAsNoTracking(a => a.hospital_id == hid && a.user_phone == phone).FirstOrDefault();
            T_Login_Record record = null;
            // 注册
            if (user == null)
            {
                user = GetT_User(hid, phone);
                if (!Add(user))
                    return CodeStatus.error_301.GetStatus($"注册失败");

                record = GetT_Login_Record(user.user_id, LoginTypeEnum.type_reg.GetEnumDesc(), ipaddr);
                if (!T_Login_RecordDal.Add(record))
                    return CodeStatus.error_301.GetStatus("记录失败");

                res.data = new { userid = user.user_id, hid = user.hospital_id, is_pwd = false };
                return res;
            }

            // 登录
            if (string.IsNullOrWhiteSpace(user.user_password))
                res.data = new { userid = user.user_id, hid = user.hospital_id, is_pwd = false };
            else
                res.data = new { userid = user.user_id, hid = user.hospital_id, is_pwd = true };

            record = GetT_Login_Record(user.user_id, LoginTypeEnum.type_login.GetEnumDesc(), ipaddr);
            if (!T_Login_RecordDal.Add(record))
                return CodeStatus.error_301.GetStatus("记录失败");

            return res;
        }

        public ResultInfo Login(string hid, string phone, string pwd, string ipaddr, string ticket, string code)
        {
            if (string.IsNullOrEmpty(hid))
                return CodeStatus.error_201.GetStatus($"{nameof(hid)}必传");
            if (string.IsNullOrEmpty(phone))
                return CodeStatus.error_201.GetStatus($"{nameof(phone)}必传");
            if (string.IsNullOrEmpty(pwd))
                return CodeStatus.error_201.GetStatus($"{nameof(pwd)}必传");
            if (string.IsNullOrEmpty(ipaddr))
                return CodeStatus.error_201.GetStatus($"{nameof(ipaddr)}必传");
            if (string.IsNullOrEmpty(ticket))
                return CodeStatus.error_201.GetStatus($"{nameof(ticket)}必传");
            Guid gid;
            if (!Guid.TryParse(ticket, out gid))
                return CodeStatus.error_201.GetStatus($"{nameof(ticket)}格式不正确");
            if (string.IsNullOrEmpty(code))
                return CodeStatus.error_201.GetStatus($"{nameof(code)}必传");

            T_Ticket_Record ticketRecord = T_Ticket_RecordDal.GetAsNoTracking(a => a.check_ticket == gid).FirstOrDefault();
            if (ticketRecord == null)
                return CodeStatus.error_203.GetStatus("失效");
            if (ticketRecord.check_code != code)
                return CodeStatus.error_203.GetStatus("不正确");

            T_User resultUser = new T_User();
            bool isPwd = false, isSuper = false;
            pwd = DesUtils.Encrypt(pwd);

            // 超管
            SuperUser superUser = new SuperUser();
            if (superUser.phone == phone)
            {
                if (DesUtils.Encrypt(superUser.pwd) != pwd)
                    return CodeStatus.error_204.GetStatus();

                resultUser.user_id = superUser.userid;
                resultUser.user_password = superUser.pwd;
                isPwd = !isPwd;
                isSuper = !isSuper;
            }
            else
            {
                T_User user = GetAsNoTracking(a => a.user_phone == phone && a.hospital_id == hid).FirstOrDefault();
                if (user == null)
                    return CodeStatus.error_202.GetStatus("未注册");

                if (user.user_password != pwd)
                    return CodeStatus.error_204.GetStatus();

                resultUser.user_id = user.user_id;
                resultUser.user_password = user.user_password;

                if (!string.IsNullOrWhiteSpace(user.user_password))
                    isPwd = !isPwd;
            }

            T_Login_Record record = GetT_Login_Record(resultUser.user_id, LoginTypeEnum.type_login.GetEnumDesc(), ipaddr);
            if (!T_Login_RecordDal.Add(record))
                return CodeStatus.error_301.GetStatus("记录失败");

            ResultInfo res = CodeStatus.success.GetStatus();
            res.data = new { userid = resultUser.user_id, hid = hid, is_pwd = isPwd, is_super = isSuper };

            return res;
        }

        public ResultInfo EditPassword(string userid, string hid, string pwd, string repeat_pwd)
        {
            if (string.IsNullOrEmpty(userid))
                return CodeStatus.error_201.GetStatus($"{nameof(userid)}必传");
            if (string.IsNullOrEmpty(hid))
                return CodeStatus.error_201.GetStatus($"{nameof(hid)}必传");
            if (string.IsNullOrEmpty(pwd))
                return CodeStatus.error_201.GetStatus($"{nameof(pwd)}必传");
            if (string.IsNullOrEmpty(repeat_pwd))
                return CodeStatus.error_201.GetStatus($"{nameof(repeat_pwd)}必传");

            if (pwd != repeat_pwd)
                return CodeStatus.error_205.GetStatus();

            T_User user = T_UserDal.Get(a => a.user_id == userid && a.hospital_id == hid).FirstOrDefault();
            if (user == null)
                return CodeStatus.error_202.GetStatus("无用户");
            user.user_password = DesUtils.Encrypt(pwd);
            user.up_userid = userid;
            user.up_time = DateTime.Now;

            if (!Up(user))
                return CodeStatus.error_301.GetStatus("修改密码失败");

            return CodeStatus.success.GetStatus();
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="hid"></param>
        /// <returns></returns>
        public ResultInfo GetPersonalInfo(string userid, string hid)
        {
            if (string.IsNullOrEmpty(userid))
                return CodeStatus.error_201.GetStatus($"{nameof(userid)}必传");
            if (string.IsNullOrEmpty(hid))
                return CodeStatus.error_201.GetStatus($"{nameof(hid)}必传");

            T_User user = GetAsNoTracking(a => a.user_id == userid && a.hospital_id == hid).FirstOrDefault();
            if (user != null)
                return CodeStatus.error_202.GetStatus("无用户");

            object objUser = new
            {
                userid = user.user_id,
                idcard = StringUtils.ReplaceWithSpecialChar(user.user_idcard),
                // phone = StringUtils.ReplaceWithSpecialChar(user.user_phone),
                name = user.user_name,
                sex = user.user_sex,
                birthday = user.user_birthday
            };

            ResultInfo res = CodeStatus.success.GetStatus();
            res.data = objUser;
            return res;
        }

        public ResultInfo GetUser(string userid, string hid)
        {
            if (string.IsNullOrEmpty(userid))
                return CodeStatus.error_201.GetStatus($"{nameof(userid)}必传");
            if (string.IsNullOrEmpty(hid))
                return CodeStatus.error_201.GetStatus($"{nameof(hid)}必传");

            T_User user = T_UserDal.GetAsNoTracking(a => a.user_id == userid && a.hospital_id == hid).FirstOrDefault();
            if (user == null)
                return CodeStatus.error_202.GetStatus("无用户");

       
            bool isPwd = ExistsExPassword(user.user_password);
            bool isFull = IsFieldFull(user);
            bool isGroup = false;

            // 查询是否是领导
            int administrator = EmployeeTypeEnum.administrator.GetHashCode();
            T_Employee employee = T_EmployeeDal.GetAsNoTracking(a => a.hospital_id == hid && a.is_leader == administrator && a.idcard == user.user_idcard && a.phone == user.user_phone && a.name == a.name).FirstOrDefault();
            if (employee != null)
                isGroup = !isGroup;

            object objResult = new
            {
                userid = user.user_id,
                name = user.user_name,
                sex = user.user_sex,
                is_pwd = isPwd,
                is_full = isFull,
                is_group = isGroup
            };

            ResultInfo res = CodeStatus.success.GetStatus();
            res.data = objResult;
            return res;
        }


        public ResultInfo SendCode(string userid, string hid, string phone)
        {
            if (string.IsNullOrEmpty(userid))
                return CodeStatus.error_201.GetStatus($"{nameof(userid)}必传");
            if (string.IsNullOrEmpty(hid))
                return CodeStatus.error_201.GetStatus($"{nameof(hid)}必传");
            if (string.IsNullOrEmpty(phone))
                return CodeStatus.error_201.GetStatus($"{nameof(phone)}必传");

            T_User user = null;
            ResultInfo res = CompareUserPhone(userid, hid, phone, out user);
            if (res.code != CodeStatus.success.GetHashCode())
                return res;

            return MsgService.SendCode(phone);
        }

        public ResultInfo EditPhone(string userid, string hid, string phone, string code)
        {
            if (string.IsNullOrEmpty(userid))
                return CodeStatus.error_201.GetStatus($"{nameof(userid)}必传");
            if (string.IsNullOrEmpty(hid))
                return CodeStatus.error_201.GetStatus($"{nameof(hid)}必传");
            if (string.IsNullOrEmpty(phone))
                return CodeStatus.error_201.GetStatus($"{nameof(phone)}必传");
            if (!VerifyHelper.IsPhone(phone))
                return CodeStatus.error_201.GetStatus("手机号不合法");
            if (string.IsNullOrEmpty(code))
                return CodeStatus.error_201.GetStatus($"{nameof(code)}必传");

            ResultInfo res = VerifyHelper.VeifyCode(phone, code);
            if (res.code != CodeStatus.success.GetHashCode())
                return res;
            T_User user = null;
            res = CompareUserPhone(userid, hid, phone, out user);
            if (res.code != CodeStatus.success.GetHashCode())
                return res;

            user.user_phone = phone;
            user.up_userid = userid;
            user.up_time = DateTime.Now;

            if (!Up(user))
                return CodeStatus.error_301.GetStatus("修改失败");

            return CodeStatus.success.GetStatus();
        }

        public ResultInfo EditUser(string userid, string hid, string idcard, string sex, string birthday, string name)
        {
            if (string.IsNullOrEmpty(userid))
                return CodeStatus.error_201.GetStatus($"{nameof(userid)}必传");
            if (string.IsNullOrEmpty(hid))
                return CodeStatus.error_201.GetStatus($"{nameof(hid)}必传");
            if (string.IsNullOrEmpty(idcard))
                return CodeStatus.error_201.GetStatus($"{nameof(idcard)}必传");
            if (!idcard.Contains("*") && !VerifyHelper.IsIDCard(idcard))
                return CodeStatus.error_201.GetStatus($"身份证号不合法");
            if (string.IsNullOrEmpty(name))
                return CodeStatus.error_201.GetStatus($"{nameof(name)}必传");
            if (string.IsNullOrEmpty(sex))
                return CodeStatus.error_201.GetStatus($"{nameof(sex)}必传");
            if (string.IsNullOrEmpty(birthday))
                return CodeStatus.error_201.GetStatus($"{nameof(birthday)}必传");

            T_User user = Get(a => a.user_id == userid && a.hospital_id == hid).FirstOrDefault();
            if (user == null)
                return CodeStatus.error_202.GetStatus("无用户");

            user.user_name = name;
            user.user_sex = sex;
            user.user_birthday = birthday;
            user.up_userid = userid;
            user.up_time = DateTime.Now;
            if (!idcard.Contains("*"))
                user.user_idcard = idcard;

            if (!Up(user))
                return CodeStatus.error_301.GetStatus("修改用户信息失败");

            return CodeStatus.success.GetStatus();
        }

        private ResultInfo CompareUserPhone(string userid, string hid, string phone, out T_User user)
        {
            user = T_UserDal.Get(a => a.user_id == userid && a.hospital_id == hid).FirstOrDefault();
            if (user == null)
                return CodeStatus.error_202.GetStatus("无用户");
            if (user.user_phone == phone)
                return CodeStatus.error_227.GetStatus();

            T_User userPhone = T_UserDal.GetAsNoTracking(a => a.hospital_id == hid && a.user_phone == phone).FirstOrDefault();
            if (userPhone != null && userPhone.user_id != user.user_id)
                return CodeStatus.error_228.GetStatus($"{userPhone.user_phone}");

            return CodeStatus.success.GetStatus();
        }

        private T_Login_Record GetT_Login_Record(string loginid, string login_type, string ipaddr)
        {
            T_Login_Record T_Login_Record = new T_Login_Record();
            T_Login_Record.id = T_Login_RecordDal.GetNextId(a => a.id, true, true, true, 7);
            T_Login_Record.ip_address = ipaddr;
            T_Login_Record.user_id = loginid;
            T_Login_Record.login_type = login_type;
            T_Login_Record.create_userid = loginid;
            T_Login_Record.create_time = DateTime.Now;
            return T_Login_Record;
        }

        private T_User GetT_User(string hid, string phone)
        {
            T_User user = new T_User();
            user.user_id = IDGeneratorUtils.Guid16StringID();
            user.user_phone = phone;
            user.create_userid = user.user_id;
            user.create_time = DateTime.Now;
            user.hospital_id = hid;
            return user;
        }

        private bool ExistsExPassword(string pwd)
        {
            bool isPwd = true;

            if (string.IsNullOrWhiteSpace(pwd))
                isPwd = false;

            return isPwd;
        }


        private bool IsFieldFull(T_User user)
        {
            bool isFull = true;

            if (string.IsNullOrWhiteSpace(user.user_name))
                isFull = false;

            if (string.IsNullOrWhiteSpace(user.user_idcard))
                isFull = false;

            if (string.IsNullOrWhiteSpace(user.user_sex))
                isFull = false;

            if (string.IsNullOrWhiteSpace(user.user_birthday))
                isFull = false;

            return isFull;
        }

    }
}
